
package processing;

import java.util.Stack;

import model.semantics.AbstractToken;
import model.semantics.OperationToken;

/**
 * Processor class for operators. Used to processes tokens via reflection.
 * @author Troy Ferrell
 *
 */
public class OperatorTokenProcessor extends AbstractTokenProcessor 
{
	/**
	 * Process operators according to the Shunting-Yard algorithm.
	 */
	@Override
	public void process(AbstractToken token, Stack<AbstractToken> operators,
			Stack<AbstractToken> operands) 
	{
		while (!operators.empty() && token instanceof OperationToken 
				&& operators.peek() instanceof OperationToken)
		{
			if (shouldShuntOperator((OperationToken)token, (OperationToken)operators.peek())) 
			{
				operands.add(operators.pop());
				continue;
			}
			break;
		}
		operators.push(token);
	}
	
	/**
	 * Checks if either case is true for the operator op1 to be shunted by
	 * comparing precedences.
	 */
	private boolean shouldShuntOperator(OperationToken op1, OperationToken op2) 
	{
		// Check for op1 is left associative case
		boolean shuntingCase1 = op1.isLeftAssociative()
				&& (op1.comparePrecedence(op2) <= 0);

		// If op1 is not left associative, then it is must be right associative
		boolean shuntingCase2 = !op1.isLeftAssociative()
				&& (op1.comparePrecedence(op2) < 0);

		return shuntingCase1 || shuntingCase2;
	}
}
